package com.c2b.algorithm.leetcode.base;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * <a href='https://leetcode.cn/problems/most-common-word/'>最常见的单词(Most Common Word)</a>
 * <p>给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多，同时不在禁用列表中的单词。</p>
 * <p>题目保证至少有一个词不在禁用列表中，而且答案唯一。</p>
 * <p>禁用列表中的单词用小写字母表示，不含标点符号。段落中的单词不区分大小写。答案都是小写字母。</p>
 *
 * <p>
 * <b>示例：</b>
 * <pre>
 * 示例：
 *      输入:
 *          paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."
 *          banned = ["hit"]
 *      输出: "ball"
 *      解释:
 *          "hit" 出现了3次，但它是一个禁用的单词。
 *          "ball" 出现了2次 (同时没有其他单词出现2次)，所以它是段落里出现次数最多的，且不在禁用列表中的单词。
 *      注意，所有这些单词在段落里不区分大小写，标点符号需要忽略（即使是紧挨着单词也忽略， 比如 "ball,"），
 *      "hit"不是最终的答案，虽然它出现次数更多，但它在禁用单词列表中。
 * </pre>
 * </p>
 *
 * <p>
 * <b>提示：</b>
 *     <ul>
 *         <li>1 <= 段落长度 <= 1000</li>
 *         <li>0 <= 禁用单词个数 <= 100</li>
 *         <li>1 <= 禁用单词长度 <= 10</li>
 *         <li>答案是唯一的, 且都是小写字母 (即使在 paragraph 里是大写的，即使是一些特定的名词，答案都是小写的。)</li>
 *         <li>paragraph 只包含字母、空格和下列标点符号!?',;.</li>
 *         <li>不存在没有连字符或者带有连字符的单词。</li>
 *         <li>单词里只包含字母，不会出现省略号或者其他标点符号。</li>
 *     </ul>
 * </p>
 *
 * @author c2b
 * @since 2023/12/18 14:47
 */
public class LC0819MostCommonWord_S {
    static class Solution {
        public String mostCommonWord(String paragraph, String[] banned) {
            Set<String> set = new HashSet<>();
            for (String ban : banned) {
                set.add(ban);
            }
            String ans = null;
            Map<String, Integer> cntMap = new HashMap<>();
            char[] chars = paragraph.toCharArray();
            for (int i = 0; i < chars.length; ) {
                // 如果是标点符号
                if (!Character.isLetter(chars[i])) {
                    ++i;
                } else {
                    // 如果是字符，从当前位置开始直到末尾或者下一个非字母的位置
                    int j = i;
                    while (j < chars.length && Character.isLetter(chars[j])) {
                        j++;
                    }
                    // 将当前字符串截取出来
                    String subStr = paragraph.substring(i, j).toLowerCase();
                    // 非单词位置的下一个位置对应的字符
                    i = j + 1;
                    if (!set.contains(subStr)) {
                        cntMap.put(subStr, cntMap.getOrDefault(subStr, 0) + 1);
                        if (ans == null || cntMap.get(subStr) > cntMap.get(ans)) {
                            ans = subStr;
                        }
                    }
                }
            }
            return ans;
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.mostCommonWord("Bob hit a ball, the hit BALL flew far after it was hit.", new String[]{"hit"}));
    }
}
